## Sid Meier's Civilization 4
## Copyright Firaxis Games 2005
## 
## Author : TheLopez - Mobile Hospital Utilities
## 

from CvPythonExtensions import *
import CvUtil
import PyHelpers
import CvConfigParser

PyPlayer = PyHelpers.PyPlayer
PyGame = PyHelpers.PyGame()
PyInfo = PyHelpers.PyInfo
BuildingInfo = PyInfo.BuildingInfo
gc = CyGlobalContext()	

import pickle

################# SD-UTILITY-PACK ###################
import SdToolKit
sdEcho         = SdToolKit.sdEcho
sdModInit      = SdToolKit.sdModInit
sdModLoad      = SdToolKit.sdModLoad
sdModSave      = SdToolKit.sdModSave
sdEntityInit   = SdToolKit.sdEntityInit
sdEntityExists = SdToolKit.sdEntityExists
sdGetVal       = SdToolKit.sdGetVal
sdSetVal       = SdToolKit.sdSetVal

# Increase or decrease the value to change the amount field hospitals will
# heal units. For example the default value of 0.15 translates to the field
# hospital healing units 15% each turn.
# Default value is 0.15
g_iFieldHospitalHealingAmount = 0.15

# Change this to enable or disable the bonus great doctors give when in the
# same plot as field hospitals.
# Default value is false
g_bGreatDoctorsStaffFieldHospitals = false

# Increase or decrease the value to change the impact great doctors have when 
# in the same plot as a field hospital. The higher the number the more a 
# damaged unit will be healed. The default value represents a 50% increase in 
# healing when a great doctor is present at a plot with a field hospital. When 
# g_iFieldHospitalHealingAmount is set to 0.15 and the value of 
# g_iGreatDoctorFieldHospitalBonus is set to 0.5 field hospitals will then heal 
# units 22.5% each turn.
# Default value is 0.5
g_iGreatDoctorFieldHospitalBonus = 0.5

class FieldHospitalUtils:

	def __init__(self):
		self.firsttime = true
		
		# Setup the mercenary data structure if it hasn't been setup yet.
		if(sdEntityExists("Great Doctor", "FieldHospitalData") == False):
			self.setupFieldHospitalData()

		global g_iFieldHospitalHealingAmount
		global g_bGreatDoctorsStaffFieldHospitals
		global g_iGreatDoctorFieldHospitalBonus
		
		config = CvConfigParser.CvConfigParser("ViSa_v3.ini")

		if(config != None):
			g_iFieldHospitalHealingAmount = config.getfloat("Great Doctor", "Field Hospital Healing Amount", 0.15)

			g_bGreatDoctorsStaffFieldHospitals = config.getboolean("Great Doctor", "Great Doctors Staff Field Hospitals", false)

			g_iGreatDoctorFieldHospitalBonus = config.getfloat("Great Doctor", "Great Doctor Field Hospital Bonus", 0.5)


	# Saves the field hospital location data if the plot found in the location
	# contains a field hospital.
	def saveFieldHospitalData(self, iX, iY):
	
		# Setup the mercenary data structure if it hasn't been setup yet.
		if(sdEntityExists("Great Doctor", "FieldHospitalData") == False):
			self.setupFieldHospitalData()
				
		# Get the plot from the map
		plot = gc.getMap().plot(iX, iY)
		
		# Return immediately if the plot at (iX,iY) does not contain a field hospital.
		if(not self.plotContainsFieldHospital(plot)):
			return
			
		point = (iX, iY)
	
		fieldHospitalData = sdGetVal("Great Doctor","FieldHospitalData","FieldHospitalData")
		
		fieldHospitalData[str(iX) + ":" + str(iY)] = point
		
		sdSetVal("Great Doctor","FieldHospitalData","FieldHospitalData", fieldHospitalData)
		
		
	# Returns true if the plot passed in contains a field hospital, false otherwise.
	def plotContainsFieldHospital(self, objPlot):

		# Return false immediately if the plot passed in is invalid
		if(objPlot == None):
			return false

		iFieldHospital = gc.getInfoTypeForString("IMPROVEMENT_FIELD_HOSPITAL")
		
		return (objPlot.getImprovementType() == iFieldHospital)
				
	
	# Goes through the units found at the plot passed in and heals them the 
	# appropriate amount.
	def healUnits(self, objPlot):
	
		iGreatDoctor = gc.getInfoTypeForString("UNIT_DOCTOR")

		# Return immediately if the plot passed in is invalid
		if(objPlot == None):
			return
			
		# Return immediately if the plot passed in does not contain a field
		# hospital.
		if(not self.plotContainsFieldHospital(objPlot)):
			return
				
		unitList = self.getPlotUnitList(objPlot)
		
		iHealAmount = g_iFieldHospitalHealingAmount
		
		# If the mod is configured to give healing bonuses from the Great 
		# Doctors, then multiply the healing amount by their bonus amount
		if(g_bGreatDoctorsStaffFieldHospitals):
			iGreatDoctorCount = self.getPlotUnitTypeCount(iGreatDoctor, objPlot)
			
			if(iGreatDoctorCount > 0):
				iHealAmount = iHealAmount * g_iGreatDoctorFieldHospitalBonus
			
		# Go through each of the units and heal them
		for unit in unitList:

			# Get the unit's current damage
			iDamage = unit.getDamage()
			
			# Calculate how much damage to heal
			iHealing = unit.getDamage() * iHealAmount

			# Get the units new calculated damage
			iDamage = int(iDamage - iHealing)
			
			# Set the new damage amount to the unit
			unit.setDamage(iDamage, PlayerTypes.NO_PLAYER)

			# Set the interface as dirty in the info pane in case the player has those
			# units selected.
			CyInterface().setDirty(InterfaceDirtyBits.InfoPane_DIRTY_BIT, true)
		
				
	# This method will setup the appropriate datastructures using the SD-Toolkit to maintain
	# the field hospital data.
	def setupFieldHospitalData(self):
	
		# The dictionary of field hospital plot dictionary.
		plotDict = {}
		fieldHopitalData = {
							"FieldHospitalData" : plotDict
		}
									
		sdEntityInit("Great Doctor", "FieldHospitalData", fieldHopitalData)


	# Gets the number of types of units in the plot passed in.
	def getPlotUnitTypeCount(self, iUnitType, objPlot):
		
		iUnitCount = 0
		
		# Return 0 immediately if the iUnitType value passed in is invalid.
		if(gc.getUnitInfo(iUnitType) == None):
			return 0

		# Return 0 immediately if the objPlot passed in is invalid
		if(objPlot == None):
			return 0
		
		# Get the units on the plot
		unitList = self.getPlotUnitList(objPlot)
		
		# Go through the units found on the plot and count up the ones that
		# match the iUnitType
		for unit in unitList:
			# If the current unit's type matches the iUnitType, count them
			if(unit.getUnitType == iUnitType):
				iUnitCount = iUnitCount + 1
				
		return iUnitCount
						
			
	# Returns the list of units on a particular plot
	def getPlotUnitList(self,objPlot):
		' unitList - All of the units in the objPlot'
		unitList = []

		# Return immediately if the objPlot is not valid
		if(objPlot == None):
			return []
			
		unitCount = objPlot.getNumUnits()

		# Go through all of the units in a plot
		for i in range(unitCount):

			# Get the unit from the plot
			unit = objPlot.getUnit(i)
			
			# If the unit isn't dead then add them to the list
			if(not unit.isDead()):
				unitList.append(unit)
		
		return unitList
